﻿using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;
using RazakiBLL.Entities;

namespace RazakiBLL.Managers
{
    public class NewTagRps : RpsRazaki<NewTag>
    {
        public NewTagRps(ObjectContext context)
            : base(context)
        {
        }

        #region >>>Fields<<<

        private List<NewTag> _lastChildrenForParentId;

        #endregion

        /// <summary>
        /// cached
        /// </summary>
        /// <returns></returns>
        public override List<NewTag> GetAll()
        {
            var result = UtilitiesBLL.CacheProvider.GetData<List<NewTag>>("AllNewTags");

            if (result == null)
            {
                result = base.GetAll();
                UtilitiesBLL.CacheProvider.SetData("AllNewTags", result);
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id">Child Id</param>
        /// <returns>Childern Ids With Queue Desc</returns>
        public Dictionary<string, int> GetChildernInSameRootByChildId(short id)
        {
            var firstParent = GetFirstParentByLastChildId(id);

            return GetChildernInSameRoot(firstParent.Id);
        }

        public Dictionary<string, int> GetChildernInSameRoot(short firstParentId)
        {
            var childrenIds = (from nT in GetLastChildrenForParentId(firstParentId) select nT.Id).ToList();

            //دلیل برگرداندن
            //int
            //بجای
            //short:
            //در 
            //UI
            //با 
            //int
            //کار می شود.
            Dictionary<string, int> result = new Dictionary<string, int>();

            foreach (var childId in childrenIds)
            {
                var descQueue = GetDescQueue(childId);
                result.Add(descQueue, childId);
            }

            return result;
        }

        public List<NewTag> GetAllParents()
        {
            var result = (from nT in GetAll()
                          where !nT.ParentId.HasValue
                          orderby nT.Desc
                          select nT).ToList();

            return result;
        }

        /// <summary>
        /// ریشه مینوسافت برگردانده نمی شود.
        /// </summary>
        /// <returns>بر اساس فیلد توضیحات مرتب شده است</returns>
        public List<NewTag> GetAllParents(List<ENewTagExceptionFirstParents> exceptions)
        {
            var result = GetAllParents().Where(x => !exceptions.ConvertAll<string>(y => y.ToString()).Contains(x.Name)).ToList();

            return result;
        }

        public NewTag GetFirstParent(string name)
        {
            //ممکن است فرزندی باشد که هم نام یکی از والد های اول باشد و ...
            var result =
                (from nT in GetAll() where nT.Name == name && !nT.ParentId.HasValue select nT).SingleOrDefault();

            return result;
        }

        //Category----

        public NewTag GetFirstParentByLastChildId(short id)
        {
            var item = GetById(id);

            if (item != null && item.ParentId.HasValue)
                return GetFirstParentByLastChildId(item.ParentId.Value);

            return item;
        }

        private List<NewTag> GetLastChildrenForParentId(short id)
        {
            if (!GetById(id).ParentId.HasValue)
                _lastChildrenForParentId = new List<NewTag>();

            var children =
                (from nT in GetAll() where nT.ParentId.HasValue && nT.ParentId.Value == id select nT).ToList();

            if (children.Count > 0)
                foreach (var child in children)
                    GetLastChildrenForParentId(child.Id);
            else
                _lastChildrenForParentId.Add(GetById(id));

            return _lastChildrenForParentId;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="id">
        /// برای شروع 
        /// id
        /// فرزند آخر فرستاده می شود.
        /// </param>
        /// <returns></returns>
        public string GetDescQueue(short id)
        {
            var item = GetById(id);
            string desc = item.Desc;

            //Id	    Name		Desc		ParentId
            //----
            //6	        minoosoft	مینوسافت	NULL
            //11	    itself		NULL		6
            //توضیح:
            //itself
            //به خود والد اشاره می کند و نامش ثابت است.
            if (item.Name == "itself")
                desc = string.Empty;
            if (!item.ParentId.HasValue)
                return desc;

            return string.Format("{0}{1}{2}", GetDescQueue(item.ParentId.Value), !string.IsNullOrWhiteSpace(desc) ? "/" : "", desc);
        }

        public NewTag GetMinoosoftFirstParentNewTag()
        {
            var minoosoft = ENewTagExceptionFirstParents.minoosoft.ToString();
            var result = (from n in _objectSet
                          where
                              n.Name.ToLower() == minoosoft &&
                              !n.ParentId.HasValue
                          select n).First();
            
            return result;
        }

    }
}
